/*********************************************************************************
 *      Copyright:  (C) 2025 LingYun<iot25@lingyun>
 *                  All rights reserved.
 *
 *       Filename:  main.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(12/04/25)
 *         Author:  LingYun <iot25@lingyun>
 *      ChangeLog:  1, Release initial version on "12/04/25 14:06:13"
 *                 
 ********************************************************************************/
#include <time.h>
#include <stdio.h>
#include <netdb.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>

#include "logger.h"
#include "get_time.h"
#include "get_temp.h"
#include "pack_data.h"
#include "socket.h"
#include "sqlite.h"
#define DEFAULT_LOG_FILE "client.log"
#define DEFAULT_DB_FILE "ds18b20.db"
#define DEFAULT_DEVICE_ID "001"
#define DEFAULT_INTERVAL 30

//#define log_level        log_error
// 全局变量声明
int print_usage(char *progname);
/* 函数声明 */
int main(int argc, char **argv)
{
	char				*hostname = NULL;							
	int			         port = 0;									
	char				*device_id = DEFAULT_DEVICE_ID;							
	int			 	 	 interval_sec = DEFAULT_INTERVAL;						
	char				*db_name = DEFAULT_DB_FILE;					
	char				*log_filename = DEFAULT_LOG_FILE;					
	int				     daemon_flag = 0;							
	int			         sample_flag = 0;							
	time_t				 pretime = 0;								
	time_t				 nowtime = 0;								
	char			 	 data[2048] = {0};							
//	char			 	 query_data[128] = {0};						
	socket_t			 sock={0};										
	packet_t			 pack;										
	int			 	 	 ch = -1;
	int                  log_level = LOG_LEVEL_INFO;  // 改为使用logger.h定义的级别
    long                 log_size = 1024;
    int                  log_lock = 1;
	struct option		 opts[] =							 
	{
		{"ipaddr", required_argument, NULL, 'i'},
		{"port", required_argument, NULL, 'p'},
		{"serial", required_argument, NULL, 's'},
		{"interval", required_argument, NULL, 't'},
		{"help", no_argument, NULL, 'h'},
		{"daemon", no_argument, NULL, 'd'},
		{"sqlite", no_argument, NULL, 'q'},
		{NULL, 0, NULL, 0}
 	};


	/*命令行参数解析 */
	while( (ch = getopt_long(argc, argv, "i:p:s:t:h:q", opts, NULL)) != -1 )
	{
		switch( ch )
		{
			case 'i':
				hostname = optarg; 			/* 服务器ip/主机名/域名 */
				break;
			case 'p':
				port = atoi(optarg); 		/* 服务器端口号 */
				break;
			case 's':
				device_id = optarg; 		/* 设备id */
				break;
			case 't':
				interval_sec = atoi(optarg);/* 采样时间间隔 */
				break;
			case 'd':
                daemon_flag = !daemon_flag;
				break;
        	case 'h': 
				print_usage(argv[0]); 		/* 打印帮助信息 */
	            break;
			case 'q':  // 查询模式
    			 packet_t pack;
   				 if (db_query(&pack) == 0)
				 {
        			printf("最新记录: %s | %s | %.2f°C\n", 
              		 pack.dev_id, pack.dev_time, pack.dev_temp);
    			 }
    			exit(0);
   				
				return 0;
		}
	}

	if( (!hostname) || (!port) )				/* 判断输入参数是否合法 */
	{											
		print_usage(argv[0]);					/* 打印帮助信息 */
		return 0;
	}
	printf("socket[%s:%d]\n", hostname, port);
	if (daemon_flag)
	{
        daemon(1, 0);
        log_filename = DEFAULT_LOG_FILE;  // 强制使用日志文件
    }


	log_open(log_filename, log_level, log_size, log_lock);
	printf("日志文件初始化打开\n");

	socket_init(&sock,hostname,port);/* 初始化socket */ 
	printf("socket 初始化成功\n");
	if (socket_init(&sock, hostname, port) != 0)
	{
    	log_error("Socket initialization failed");
    	return -1;
	}

	if ( db_init(db_name)!= 0 )     	      /* 初始化数据库 */
	{		
		log_error("database initialization failed\n");
		return -1;
	}
	printf("数据库初始化成功\n");
	
	pretime = 0;
	printf("0\n");
	while( 1 )
	{
        //未采集 
		sample_flag = 0;												
		time(&nowtime);
	//	printf("Before check: nowtime = %ld, pretime = %ld\n", nowtime, pretime);
		if ( (nowtime - pretime) >= interval_sec )/* 判断是否到采集时间 */
		{																


			memset(&pack, 0, sizeof(pack));
			strncpy(pack.dev_id, device_id, sizeof(pack.dev_id));		/* 设备id */
			get_time(pack.dev_time);									/* 获取当前日期时间 */
			get_temp(&pack.dev_temp);									/* 采集温度 */
			sample_flag = 1;											
			pretime = nowtime;
			printf("[%s] 设备ID: %s | 温度: %.2f°C |\n ",pack.dev_time, pack.dev_id, pack.dev_temp);

			
		}
        
		//socket_diag(&sock);				
		printf("socket_connect: %s\n",socket_connect);
		//判断连接
        if ( !sock.connected )			
		{		
			socket_connect(&sock);		
		
	
			if ( 1 == sample_flag )		
				db_insert(&pack);//将采集的数据插入数据库中
		}
		 usleep(100000);//Sleep for100ms to reduce CPU usage
		sleep(3);
		 continue;
		printf("连接失败\n");

		//连接成功
		if ( 1 == sample_flag )	
		{					
            //将采集的数据从pack打包到data							
			pack_data(&pack, data, sizeof(data)); //传递缓冲区总大小	
			//发送数据 
			int data_len=pack_data(&pack, data, sizeof(data));
            if ( data_len > 0 && socket_write(&sock, data, data_len) < 0 )	
			{													
				db_insert(&pack);								
				socket_close(&sock);							
			}
		}
		printf("连接成功\n");
		printf("已连接，无需重新连接\n");
    	// 打印连接成功后的时间
    	printf("连接成功后时间: %ld\n", nowtime);
		if ( 0 == db_query(&pack) )								/* 查询数据库是否有数据 */ 
		{
			memset(data, 0, sizeof(data));
			pack_data(&pack, data, sizeof(data));				/* 将查询到的数据pack打包到data中 */
			//发送数据data
            if ( socket_write(&sock, data, strlen(data)) < 0 )	
			{													
				socket_close(&sock);							
			}
			db_delete();										
         }
    }
	socket_close(&sock);
    db_close();
    log_close();
	return 0;
}

int print_usage(char *progname)
{
	if ( NULL == progname )
	{
		return -1;
		log_error("NULL pointer");
	}
	printf("%s usage: \n", progname);
	printf("-i(--ipaddr): sepcify server IP address or hostname or domain name.\n");
	printf("-p(--port): sepcify server port.\n");
	printf("-s(--serial): sepcify device serial number.\n");
	printf("-t(--time):sepcify sampling interval.\n");
	printf("-d,--daemon Run as daemon\n");
	printf("-h(--help): print help informatiom.\n");
	printf("\n");
	return 0;
}


